大家好,我們是 AI . FREE Team - 人工智慧自由團隊,這一次的鐵人賽,自由團隊將從0到1 手把手教各位讀者學會 (1)Python基礎語法 (2)Python Web 網頁開發框架 – Django (3)Python網頁爬蟲 – 周易解夢網 (4)Tensorflow AI語言模型基礎與訓練 – LSTM (5)實際部屬AI解夢模型到Web框架上。
自由團隊的成立宗旨為開發AI/新科技的學習資源,提供各領域的學習者能夠跨域學習資料科學,並透過自主學習發展協槓職涯,結合智能應用到各式領域,無論是文、法、商、管、醫領域的朋友,都可以自由的學習AI技術。
AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源
在今天會進入更後端一點的世界,我們會實作出幾支 API去處理來自用戶端的特定 Request。在這邊會提到的 Requests 總共有3個, GET, POST, 和 DELETE。
Request,表示用戶透過特定的方式"請求"伺服器端做一些操作,在這兩天的會用到的例子,都會與資料庫的操作有關係。另外,如果有牽涉到回傳或是上傳的部分,我們通常都會將資料格式轉換成 JSON 的形式(與 Python 的 List 很像,基本的格式為 {"key": “value”})。像是下方的圖片,為等一下會做出來專門處理GET Request 的API所回傳的資料,為標準的 JSON 格式。
我們今天會使用到 Django RestFramework 這個套件,來簡潔的實現API的建立。
在我們進入到下一步驟之前,先來探討 API 這個概念,英文全名是 Application Programming Interface,而中文翻譯是應用程式介面,使用者端不需要知道應用程式是如何運作的,使用者只需要知道該怎麼使用 API 就好了。生活中其實隨處可見 API 的例子,以買飲料為例,我們去飲料機投硬幣得到飲料。在這個動作裡面,飲料機就是這個動作的介面 (Interface),它負責接收硬幣,然後回傳飲料給使用者。類比到我們的使用情境,我們想要API 做到的事情是,接收到 Requests (GET, POST, DELETE)之後,會回傳給使用者一個他們需要的內容。
有了 Request 和 API 的基本概念後,我們就來安裝上面提到的 rest framework 套件吧。先進入虛擬環境,然後再安裝。
$ pipenv shell
$ pipenv install djangorestframework
成功安裝之後,打開 DI_project 中的設定檔,也就是 DI_project/ settings.py,在前幾天也有提過的 INSTALLED_APPS 這個 list 結構再多加入 "rest_framework" 這個APP,所以最後會變成下面這樣。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"demo_app.apps.DemoAppConfig",
"rest_framework",
]
新增檔案 (demo_app/ serializers.py)
首先需要在 demo_app 內多增加一個檔案,並將它命名為 serializers.py,因為它的工作就是將一連串的 model objects (ex: 學派),序列化地轉換成 JSON 格式的資料。而檔案命名使用複數(s)呈現的理由和 urls.py、views.py 是類似的,就是因為我們會有 class 是針對 Ancient_People 做 serialize、也會有 class 是針對 School 做 serialize,所以才取名為複數型。
完成上面的設定之後,我們就可以進入撰寫 API 的部分了。
首先,為了讓 Requesets 可以順利地進行,我們先將做出 serialize 的工具做好,所以先將以下內容放進 serializers.py 內。
DI_project/ demo_app/ serializers.py
from rest_framework import serializers
from demo_app.models import School
class School_Serializer(serializers.ModelSerializer):
class Meta:
model = School
fields = "__all__"
我們在這裡需要先 import rest_framework
的 serializers,然後再 import 同為 demo_app 資料夾底下的 models.py 裡面的兩個class (i.e. Ancient_People 和 School)。接著,我們看到了兩層 class 的結構,在裡面那層 Meta 的 class 必須要設定2個變數。
在有上面 serializers.py 的幫助下,等等的操作就會變得相當容易。在今天我們會先完成 查(GET)這部分的API,而在明天則會依照新增(POST)、修改(還是POST)、刪除(DELETE)的順序完成。
這裡我們寫3種查
開啟 demo_app/ views.py,將以下內容加入。
from rest_framework.decorators import api_view
from rest_framework.response import Response
from demo_app.serializers import School_Serializer
@api_view(['GET'])
def api_overview(request):
api_urls = {
'Schools List':'/school_list',
'School Detail View':'/school_detail/<int:id>',
'School Create':'/school_create',
'School Update':'/school_update/<int:id>',
'School Delete':'/task-delete/<int:id>'
}
return Response(api_urls)
@api_view(['GET'])
def school_list(request):
schools = School.objects.all()
serializer = School_Serializer(schools, many=True)
return Response(serializer.data)
@api_view(['GET'])
def school_detail(request, id):
one_school = School.objects.get(id=id)
serializer = School_Serializer(one_school, many=False)
return Response(serializer.data)
首先我們先看 import 的部分,這次我們從 rest_framework 的方法中 import 了 api_view
和 Response
。api_view
在這邊可以設定我們的 API 支援什麼樣的 Request,以目前上方有的 API 為例,全部都是只有支援 GET 類型的 Request。另外,我們也有 import demo_app.serializers
,因為我們馬上就會在這個 views.py 馬上就使用到了(i.e. School_Serializer)。
api_overview 這支API內我們一共列了5個待開發的API,大家可以注意到,我們在這邊有刻意的把資料的結構換成 JSON 的形式,也就是 { "key1": “value1”, “key2”: “value2”, ...},必須要這樣才能透過來自 rest_framework 的 Response 方法將資料傳給請求方。
接著我們看最下面那支 API (i.e. school_detail
),這支有懂,那上面那支就一定沒有問題了! 我們在這裡可以看到 school_detail
除了接收 HttpRequest 以外,還有接收 id 這個變數,這是從 url pass 進來的,我們需要這個 id 將特定的 Shcool object 取出來。(這裡算是重複了 urls.py, views.py 交互的概念)
接下來我們實體化了 School_Serializer
這個 class,想要實體化就需要提供兩個參數,一個是學派的 Object (i.e. 上面的 one_school),另一個則是 many 的設定,如果是 False
,那就表示我們只會 serialize 一個學派Object;如果是 True
的話,則表示我們預計會 serialize 不只一個學派Object,這邊的使用情境可以參考 school_list 這支API。
處理完 view 之後,我們再來把 url 也設計好。
開啟 demo_app/ urls.py,並將 urlpatterns 調整的與下方一致。在這邊,我們一起將其他尚未完成,但預計會完成的 path 也一併加入。(就是註解起來的部分)
urlpatterns = [
path("Confucianism/<int:id>", views.confucianism_detail, name="confucianism"),
path("Taoism/<int:id>", views.taoism_detail, name="taosim"),
# 以下為新增的內容
path("", views.api_overview, name="api_overview"),
path("school_list", views.school_list, name="school_list"),
path("school_detail/<int:id>", views.school_detail, name="school_detail"),
#path("school_create", views.school_create, name="school_create"),
#path("school_update/<int:id>", views.school_update, name="school_update"),
#path("school_delete/<int:id>", views.school_delete, name="school_delete")
]
至此,我們就算是階段性的完成了 GET Request 的API了,將 server run 起來。
$ python manage.py runserver
開啟瀏覽器,並搜尋以下 url,在這邊同時也呈現我看到的畫面。
對應到 name = api_overview 的 url: http://127.0.0.1:8000/demo_app/
對應到 name = school_list 的 url: http://127.0.0.1:8000/demo_app/school_list
對應到 name = school_detail/int:id 的 url: http://127.0.0.1:8000/demo_app/school_detail/7
Note: 這邊大家的 id 數字可能會不一樣喔,可以看看大家在上面的 name = school_list 有列出來的學派 id 為何,像我就是在 school_list 看到7,所以這邊的 school_detail 才用7。
有成功執行的各位,可以看在對應的URL裡看到有被自動生成的介面(此為今天下載的套件 Rest framework 產生的)。伴隨著回傳JSON型式的結果,也可以看到其他相關的資訊。
以(上圖) School Detail 為例的話:
今天提到了 API 和 Request 的基本概念,透過 Serializer 的協助,我們很快速的將針對 GET Request 的 API 建立起來了。在明天,我們會用兩種請求(一個是 POST,另一個則是 DELETE) 實作出能夠讓使用者 新增、修改、和刪除 的API。
自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/
文章同步發布於:自由團隊部落格
(想看更多文章?學習更多AI知識?敬請鎖定自由團隊的頻道!)